package main

import "fmt"

type V struct {
	X, Y float64
}

func main() {

	//MARK nil是指针零值,赋予不同类型的变量 打印出来不同 ; 就是说 map 接口 指针 函数 都是指针

	fmt.Println(nil) //<nil>

	fmt.Println("================struct================")
	var v V //这个就不是指针和nil没关系
	//v =*new(V)
	//以上2个一样
	fmt.Println(v)         //{0 0}
	fmt.Println(&v == nil) //false

	va := new(V)    //这样是得 指针
	fmt.Println(va) //&{0 0}

	var vp *V
	//vp = nil
	//MARK  ↑以上2个赋值 是一样的
	fmt.Println(vp)        //<nil>
	fmt.Println(vp == nil) //true

	fmt.Println("================interface================")
	var ni aInterface
	//ni=nil
	//MARK ↑以上2个 是一样的
	fmt.Println(ni) //<nil>

	fmt.Println("================func================")
	var fun1 func(x int) int
	//fun1 = nil
	//MARK ↑以上2个 是一样的
	fmt.Println(fun1) //<nil>

	makeInit()
}

//MARK make 这个初始化函数, 只用于初始化:  map 切片 chan
func makeInit() {
	//MARK [map 切片 chan] 只是声明出来是nil,因为本质都是指针,
	//虽然打印出来不同(可能不是<nil>), 实际上都是nil
	//MARK 必须make是因为 数据结构需要初始化才能使用, 返回值
	//For slices, maps, and channels, make initializes the internal data structure and prepares the value for use.

	fmt.Println("================map================")
	var match map[string]int //nil map MARK 不能用于存储键值对 否则报错
	//match = nil
	//↑这2个一样
	fmt.Println(match)         //map[]
	fmt.Println(&match)        //&map[]
	fmt.Println(match == nil)  //true
	fmt.Println(match["啊key"]) //0 MARK 没报错 给个0值
	//match["啊key"]=3 MARK 报错 毕竟没make
	fmt.Println(match) //map[]
	match = make(map[string]int)
	fmt.Println(match) //map[] //MARK 虽然打印出来一样 但是能用了

	fmt.Println("================slice================")
	var af []int //nil切片 MARK 在需要描述一个不存在的切片时，nil切片会很好用。例如，函数要求返回一个切片但是 发生异常的时候
	//af = nil
	//MARK ↑以上2个赋值 是一样的
	fmt.Println(af)        //[]   MARK 长度0 其实容量也是0
	fmt.Println(&af)       //&[]
	fmt.Println(af == nil) //ture
	slice := make([]int, 0)
	fmt.Println(slice) //[] MARK 空切片 一样是长度容量0 但是不等于nil

	fmt.Println("================chan================")
	var chas chan int
	fmt.Println(chas) //<nil>
	channelA := make(chan int)
	fmt.Println(channelA) //0xc0000500c0

}

type aInterface interface {
	Abs() float64
}
